package com.netrust.cmsx.admin.modules.sys.service;


import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.Transformer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.netrust.cmsx.admin.modules.sys.common.AStatic;
import com.netrust.cmsx.admin.modules.sys.security.Principal;
import com.netrust.cmsx.admin.modules.sys.utils.CacheUtils;
import com.netrust.cmsx.admin.modules.sys.utils.UserUtils;
import com.netrust.cmsx.core.exception.ProvideException;
import com.netrust.cmsx.core.jpa.Criteria;
import com.netrust.cmsx.core.jpa.Restrictions;
import com.netrust.cmsx.core.jpa.Criterion.MatchMode;
import com.netrust.cmsx.core.page.PageKey;
import com.netrust.cmsx.core.service.CrudService;
import com.netrust.cmsx.core.web.Servlets;
import com.netrust.cmsx.entity.module.sys.Role;
import com.netrust.cmsx.entity.module.sys.User;
import com.netrust.cmsx.persist.module.sys.RoleDao;
import com.netrust.cmsx.persist.module.sys.UserDao;
import com.netrust.cmsx.utils.bean.BeanUtils;
import com.netrust.cmsx.utils.collections.CollectionUtils;
import com.netrust.cmsx.utils.decode.Entrypt;
import com.netrust.cmsx.utils.net.RemoteUtils;
import com.netrust.cmsx.utils.string.StringUtils;

@Service("userService")
public class UserService extends CrudService<User,String,UserDao>{
	@Autowired
	RoleDao roleDao;

	/**
	 * 获取当前用户
	 */
	public User get(){
		return UserUtils.getUser();
	}
	
	/**
	 * 根据ID获取用户
	 * @param id
	 * @return 取不到返回null
	 */
	public User get(String id){
		return dao.findOne(id);
	}
	
	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return 取不到返回null
	 */
	public User getByLoginName(String loginName){
		return dao.findByLoginName(loginName);
	}
	
	
	/**
	 * 分页用户查询
	 * @param pk
	 * @return
	 */
	public Page<User> findList(PageKey pk){
		Criteria<User> criteria=new Criteria<User>();
		
		if(pk!=null&&pk.getKey()!=null){
			criteria.add(Restrictions.or(
								Restrictions.like("loginName",pk.getKey(),MatchMode.ANYWHERE),
								Restrictions.like("name",pk.getKey(),MatchMode.ANYWHERE),
								Restrictions.like("email",pk.getKey(),MatchMode.ANYWHERE),
								Restrictions.like("mobile",pk.getKey(),MatchMode.ANYWHERE)
							) 
						);
		}
		
		//criteria.add(Restrictions.eq("loginFlag",true));
		criteria.add(Restrictions.eq("delFlag",false));

		Page<User> page=dao.findAll(criteria, new PageRequest(
											pk.getPageNum(), 
											pk.getPageSize(), 
											new Sort(Direction.ASC, "loginDate","userType")));
		
		return page;
	}
	


	@Transactional(readOnly = false)
	public void saveUser(User user) throws Exception{
		if (StringUtils.isNotBlank(user.getId())){
			User old=dao.findOne(user.getId());
			String scPwd=old.getPassword();
			try {
				BeanUtils.copyProperties(old, user);

				if(Entrypt.validate(old.getPassword(),scPwd)){
					old.setPassword(Entrypt.entrypt(old.getNewPassword()));					
				}else{
					throw ProvideException.unchecked(new Exception("密码错误"));
				}
				
			} catch (Exception e) {
				throw ProvideException.unchecked(e);
			}
			if (CollectionUtils.isNotEmpty(user.getRoleIdList())){
				old.setRoles(null);
				
				@SuppressWarnings("unchecked")
				List<Role> roles= (List<Role>) CollectionUtils.collect(user.getRoleIdList(), new Transformer() {
					public Object transform(Object input) {
						return roleDao.findOne((String) input);
					}
				});
				old.setRoles(roles);	
			}

			this.save(old);
			
		}else{
			this.setUserRoles(user);//设置角色
			user.setWhetherNew(true);
			user.setPassword(Entrypt.entrypt(user.getPassword()));
			user.setDelFlag(false);
			this.save(user);
		}
	}
	

	private void setUserRoles(User user){
		if(CollectionUtils.isNotEmpty(user.getRoleIdList())){
			@SuppressWarnings("unchecked")
			List<Role> roles= (List<Role>) CollectionUtils.collect(user.getRoleIdList(), new Transformer() {
				public Object transform(Object input) {
					return roleDao.findOne((String) input);
				}
			});
			user.setRoles(roles);					
		}
	}
	
	@Transactional(readOnly = false)
	public void delete(User user) {
		if(user!=null&&user.getId()!=null){
			this.delete(user.getId());
			// 清除用户缓存
			UserUtils.clearCache(user);			
		}
	}
	
	@Transactional(readOnly = false)
	public void deleteInFlag(User user) {
		if(user!=null&&user.getId()!=null){
			user=dao.findOne(user.getId());
			user.setDelFlag(true);
			user.setWhetherNew(false);
			//dao.saveAndFlush(user);
			
			this.save(user);
			
			// 清除用户缓存
			UserUtils.clearCache(user);			
		}
		
	}
	
	/**
	 * 修改本人的密码
	 * @param oldPassword
	 * @param newPassword
	 */
	@Transactional(readOnly = false)
	public void updatePasswordSelf(String oldPassword, String newPassword) {
		User user = this.get();
		//密码输入正确
		if(Entrypt.validate(oldPassword, user.getPassword())){
			user.setPassword(Entrypt.entrypt(newPassword));
		}
		user.setWhetherNew(false);
		this.save(user);
		UserUtils.clearCache(user);
	}
	
	
	/**
	 * 管理员修改密码
	 * @param id
	 * @param oldPassword
	 * @param newPassword
	 */
	@Transactional(readOnly = false)
	public void updatePasswordAdmin(String id,String password) {
		User user = this.get(id);
		user.setPassword(password);
		user.setWhetherNew(false);
		this.save(user);
	}
	
	/**
	 * 更新登录信息
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void updateLoginInfo(User user) {
		// 更新本次登录信息
		user.setLoginIp(RemoteUtils.ip(Servlets.getRequest()));
		user.setLoginDate(new Date());
		this.save(user);
	}
	
	/**
	 * 删除用户某些权限
	 * @param uid
	 * @param rids
	 */
	@Transactional(readOnly = false)
	public void outUserRoles(String uid,String[] rids) {
		User user = this.findOne(uid);
		List<String> roleIds = user.getRoleIdList();

		CollectionUtils.removeAll(roleIds, Arrays.asList(rids));
		
		user.setRoleIdList(roleIds);
		
		@SuppressWarnings("unchecked")
		List<Role> roles= (List<Role>) CollectionUtils.collect(user.getRoleIdList(), new Transformer() {
			public Object transform(Object input) {
				return new Role((String) input);
			}
		});
		
		user.setWhetherNew(false);
		user.setRoles(roles);
		
		this.save(user);
	}
	
	/**
	 * 添加用户某些权限
	 * @param uid
	 * @param rids
	 * @return
	 */
	@Transactional(readOnly = false)
	public void addUserToRole(String uid,String[] rids) {
		User user = this.findOne(uid);
		List<String> roleIds = user.getRoleIdList();
		
		CollectionUtils.union(roleIds, Arrays.asList(rids));

		user.setRoleIdList(roleIds);
		
		@SuppressWarnings("unchecked")
		List<Role> roles= (List<Role>) CollectionUtils.collect(user.getRoleIdList(), new Transformer() {
			public Object transform(Object input) {
				return new Role((String) input);
			}
		});
		
		user.setWhetherNew(false);
		user.setRoles(roles);
		this.save(user);
	}
	
	
	
}
